package com.cata.mall.config;

import com.cata.mall.model.UmsResource;
import com.cata.mall.security.component.DynamicSecurityService;
import com.cata.mall.service.UmsAdminService;
import com.cata.mall.service.UmsResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @作者: Tao
 * @日期: 2025/10/11
 * @时间: 15:33
 * @描述: mall-security模块相关配置<pre>
 */
@Configuration
public class MallSecurityConfig {
    @Autowired
    private UmsAdminService adminService;
    @Autowired
    private UmsResourceService resourceService;

    /**
     * 配置用户详情服务Bean
     *
     * @return UserDetailsService 用户详情服务实例
     */
    @Bean
    public UserDetailsService userDetailsService() {
        // 返回一个Lambda表达式实现的UserDetailsService，通过adminService加载用户信息
        return username -> adminService.loadUserByUsername(username);
    }

    /**
     * 创建动态安全服务Bean
     *
     * @return DynamicSecurityService 动态安全服务实例
     */
    @Bean
    public DynamicSecurityService dynamicSecurityService() {
        return new DynamicSecurityService() {
            /**
             * 加载资源ANT通配符和资源对应MAP
             */
            @Override
            public Map<String, ConfigAttribute> loadDataSource() {
                // 创建线程安全的Map用于存储资源URL与安全配置的映射关系
                Map<String, ConfigAttribute> map = new ConcurrentHashMap<>();
                // 获取所有资源列表
                List<UmsResource> resourceList = resourceService.listAll();
                // 遍历资源列表，将资源URL作为key，资源ID和名称组合作为安全配置值存入map
                System.out.println("DynamicSecurityService = ");
                for (UmsResource resource : resourceList) {
                    map.put(resource.getUrl(), new SecurityConfig(resource.getId() + ":" + resource.getName()));
                }
                return map;
            }
        };
    }


}
